import numpy as np

# 假设数据（每行代表一个样本，每列代表一个指标，最后一列是社会秩序方面的指标）
data = np.array([
    [80, 70, 60, 75],
    [70, 85, 70, 80],
    [90, 75, 80, 90],
    [85, 80, 65, 85],
    [56, 75, 10, 96],
    [10, 69, 40, 25]
])


# 数据标准化（最小-最大标准化）
# def standardize(data):
#     min_vals = data.min(axis=0)
#     max_vals = data.max(axis=0)
#     range_vals = max_vals - min_vals
#     standardized_data = (data - min_vals) / range_vals
#     return standardized_data

# 数据标准化（最小-最大标准化，只除以最大值）
def standardize(data):
    max_vals = data.max(axis=0)
    standardized_data = data / max_vals
    return standardized_data


# 计算信息熵
def calculate_entropy(data):
    n_samples, n_features = data.shape
    epsilon = 1e-10  # 避免log(0)的情况
    p = data / data.sum(axis=0, keepdims=True)
    p = np.clip(p, epsilon, 1 - epsilon)  # 将概率值限制在[epsilon, 1-epsilon]范围内
    entropy = -np.sum(p * np.log(p), axis=0) / np.log(n_samples)
    return entropy


# 计算熵权
def calculate_entropy_weights(entropy):
    d = 1 - entropy
    return d / d.sum()


# 主观权重调整
def adjust_weights(entropy_weights, adjustment_factor_for_social_order):
    adjusted_weights = entropy_weights.copy()
    # 假设最后一列是社会秩序方面的指标
    social_order_index = len(adjusted_weights) - 1
    adjusted_weights[social_order_index] *= adjustment_factor_for_social_order
    # 重新归一化权重
    adjusted_weights /= adjusted_weights.sum()
    return adjusted_weights


# 计算社会承压指数（SPI）
def calculate_spi(standardized_data, weights):
    return np.dot(standardized_data.mean(axis=0), weights) * 100  # 乘以100是为了得到0-100范围的SPI值


# 主函数
def main():
    # 标准化数据
    standardized_data = standardize(data)

    # 计算信息熵
    entropy = calculate_entropy(standardized_data)

    # 计算熵权
    entropy_weights = calculate_entropy_weights(entropy)

    # 主观调整权重（例如，将社会秩序方面的权重增加20%）
    adjustment_factor_for_social_order = 1.2
    adjusted_weights = adjust_weights(entropy_weights, adjustment_factor_for_social_order)

    # 计算社会承压指数（SPI）
    spi = calculate_spi(standardized_data, adjusted_weights)

    # 输出结果
    print("标准化数据：\n", standardized_data)
    print("信息熵：\n", entropy)
    print("熵权：\n", entropy_weights)
    print("调整后的权重：\n", adjusted_weights)
    print("社会承压指数（SPI，0-100范围）：", spi)


if __name__ == "__main__":
    main()